1+1
多謝這年頭氾濫又充滿錯誤與偏見的科普、或敷衍了事毫無啟迪人心功能的義務教育,「我們(還沒學習寫程式)」都知道電腦是用0/1二進位做運算。
所以「1+1」應該是「00000001+00000001」。
錯!因為太簡單,所以錯。
電腦沒有辦法「閱讀」任何人類閱讀的文字,不管是二進位或N進位,當你用「+」或「加」這樣的概念描述自己希望電腦做的事情時,電腦只會呆在那邊為溫室效應做出貢獻而已。
事實上,電腦只能接受連續輸入的數字串。所以必須要用數字串表達任何自己想做的事情。
00000001,00000001,00000001
最後一個「00000001」表示「將前面兩組數字做相加」。
所以「1+1」會變成「2」,會得到00000010。
這還是錯!因為還是太簡單,所以錯。
這樣跟電腦輸入指令,結果只會讓答案消失在CPU裡而已。
必須要告訴電腦「把答案儲存在記憶體裡」。
00000001,00000001,00000001,00000010
最後一個「00000010」是記憶體位址。首先這表示電腦一共有 256*8個位元可以用來儲存資料,每個位元都有個編號。
為什麼是「256*8」?一個八位元數字最大可以表示到256,表示這可以有256組記憶體、可以儲存256組數字,但每個數字都需要8位元,所以每組記憶體其實是8位元,也就是「256*8」。
這表示「將運算的結果儲存到這個記憶體上」,這樣,只要到記憶體00000010上判讀結果,就可以知道運算結果了。
但這還是錯。不講原因,開始解釋。
要能作為「程式」,不能寫死的永遠都在計算固定數值,必須要可以彈性輸入。
所謂的「1+1」在程式的設計概念上會變成「A+B」。
00000001, 00000000, 10000000, 10000000,
00000001, 11000000, 10000000, 11000000,
10000000, 11000000, 00000001, 00000010,
第一串數字意思是說「在記憶體10000000中設定一組數字00000001」。第三個數值10000000就是「在記憶體...中設定數值...」。第二個00000000(暫時)沒有意義,隨便寫什麼都不會發揮功用,只是每次輸入電腦的數值數目都要一樣,所以才會有一個沒功能的數字在裡頭。
以此類推,第二串數字意思是說「在記憶體11000000中設定一組數字00000001」。
而第三串數字從第三個數值的00000001可以知道它是運算,是「將記憶體1000000和記憶體11000000的數值取出來做運算後存入記憶體00000010中」。
但,這依然還是錯。
不完全是錯在太簡單,主要是錯在年份不對。
現在是2020年,不是1936年的圖靈機,主流電腦也早已經不已八位元為基本的運作管理單位。
用八位元做舉例說明主要是因為好寫好讀,不想讓大家因為閱讀三十二位元數字而眼睛會抽筋。
以上這一長串是想解釋:到底程式設計是在做什麼?
常態來說,一萬個人類裡頭,有九千九百九十九個人無法用電腦的0/1、指令碼、記憶體位址等方式去做事情,--至少沒辦法做得太複雜,處理「1+1+1」大概就是大多數人的極限了。
像要思考「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」這樣的事情,基本上是不可能的,更不要提正常人可接受的技術難度水平只在「(在某個地方)輸入URL後會有網頁出現」。
至少也要把「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」這麼一長串工作也都要簡化成「發送資料到URL_X,用Html/Big5接收回傳,」這才是大多數人可以接受跟運用的「程式設計」。
從「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」到「發送資料到URL_X,用Html/Big5接收回傳。」
理解「(在某個地方)輸入URL後會有網頁出現」這件事情其實是「發送資料到URL_X,用Html/Big5接收回傳。」或「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」所構成的,然後用「發送資料到URL_X,用Html/Big5接收回傳。」或「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」這樣的概念去描述任何你希望電腦做的事情,這就是設計程式。
但「發送資料到URL_X,用Html/Big5接收回傳。」或「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」這樣的描述電腦依舊無法閱讀!
因為這終究是給人類閱讀的文字。(人類可讀性高的程式語言,又被稱為高階語言。)
要把「呼叫網路晶片,連接Port:8888,發送資料到URL_X.......準備接收回傳資料,取用資料格式Html和字碼Big5...」這一連串的工作裡的每個環節都轉成由0/1構成的指令數字串,電腦才有辦法閱讀。
其實程式就是一串又一串又一串......又一串讓電腦閱讀的數字
把人類寫在文件裡頭的程式碼轉成程式(我上面所謂的數字串),這過程叫做「編譯 Compile」。
舉例:以前寫C語言,要用「小作家」新增或修改一份文件,程式開發者就要在這份文件裡面寫入程式碼。假設這份文件的名稱叫做「iT_Game」,等寫完、寫到一個段落存檔後,工程師要到終端機模式下輸入「gcc -v iT_Game」,C語言的SDK中負責編譯的程式(剛好就叫做gcc)就會找到iT_Game的文件,然後閱讀裡面的內容、把它轉成程式後儲存在電腦硬碟裡。
聽起來挺簡單,但有無數個魔鬼藏在裡頭。
有編譯器就可以產生程式嗎?去哪取得編譯器?編譯器為什麼要用終端機操作?終端機是什麼?
光有編譯器是不夠的。因為不同廠牌的CPU或作業系統(Window?Linux?)可能會對同一件事情有不同的指令碼跟格式,所以即使是使用同一套程式碼,但編譯出來的程式會不一樣。
但編譯器本身很單純,它只負責讀取跟分析程式碼,最終要產生什麼樣的程式,必須要去相對應的「圖書館library」裡查詢。
library:一般稱為圖書館,資訊領域中的正式稱呼為套件。
如果是要產生Windows程式,那就有「Windows圖書館 Windows library」,如果是要產生Android APP,那就有「Android圖書館 Android library」。
程式碼內本身可能就包含了「告訴編譯器要使用哪套library」的指示,或者使用者要修改編譯器的「設定檔」來決定它的屬性,各種程式語言的作法可能都不一樣,在數十年的程式語言發展歷史中,各家程式語言開發者使用過各種策略,因為策略不同,有時候會帶來進步與方便、有時候會造成能殺死一堆「傻瓜」的意外。
什麼樣的意外?最常見的就是「編譯並不總是會成功」。
通常是因為library可能會損毀、遺失、或是互相矛盾。(為什麼會發生這種事情?
怎麼排除這些意外?怎麼讓編譯繼續進行下去?......簡單的方法大概是「重新安裝編譯器和取得library」,但很多時候,傻瓜們只能像亂世佳人一樣看著螢幕上名為「編譯失敗」的夕陽、流著眼淚說「下一款程式語言會更好的」。
但下一款語言通常不會更好,因為「一點虛無、兩點悲觀」,設計一款軟體有時候跟寫篇教學文或心得書,最後的命運很雷同。
一點虛無、兩點悲觀
無數的library、管理器、和編譯器組成了所謂的「軟體開發套件Software Development kit:SDK」,開發程式通常不會只去取得編譯器,而是去取得整套SDK。
比如Flutter就有自己的SDK。(點此去下載取得。)安裝方式則是參閱這裡。如果想用中文看怎麼安裝,建議可以參閱這裡。
該來說明一下什麼是終端機模式。
其實很簡單。
滑鼠和視窗模式作業系統相較下是很年輕的東西,在它們出現以前只能使用鍵盤搭配這種終端機模式作業系統操作電腦。
簡單來說,終端機模式是用來快速且明確地顯示使用者輸入了什麼文字的一種介面,就跟視窗介面可以讓使用者明確的知道滑鼠游標在哪裡、要選用的功能又在哪裡一樣,終端機模式下也有自己的邏輯去讓使用者知道「自己剛剛輸入了什麼」「自己要選用的功能在哪裡」。
Linux直到現在依然是以終端機模式為主流操作方式,(因為網路連線很方便,根本不需要那麼消耗資源、又不即時的遠端桌面。)
MacOS和Windows也都有內建終端機模式,只是Windows XP是最後一代會讓使用者(從「附屬應用程式」內)快速開啟終端機模式的作業系統,之後的Windows就沒那麼簡單。
怎麼開啟?點這裡可以看到Windows10下的方法還是挺多的,總有一個行得通。
方法挺多的,總有一個行得通。